/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pkgjeudestrategie;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import pkgapplication.UniteAerienne;
import pkgapplication.UniteDeCombat;
import pkgapplication.UniteTerrestreLegere;
import pkgapplication.UniteTerrestreLourde;
import pkgjeudestrategie.ressource.*;

/**
 *
 * @author Admin
 */
public class Territoire extends Terrain implements Serializable  {
//la population est un int (logiquement) mais le modificateur doit être double pour plus de réalisme

    int basePopulation;
    static int id = 0;
    double modificatorPopulation;
    double[] taxe = {10, 20, 30, 40, 50};
    int taxeLocation = 0;
    int hapiness;
    Route route;
    BarreSoldat barSoldat;
    LogoVille logoVille;
    boolean isPossessed = false;
    boolean isCapital = false;
    boolean isClicked = false;
    boolean isOccupied = false;
    boolean isTerrainDifficile = false;
    boolean living=true;
    int possessorPlayer = 0;
    int numberOfPlayer = -1;
    Batiment batiment1;
    Batiment batiment2;
    Batiment batiment3;
    Batiment batiment4;
    Ressource ressource1;
    Ressource ressource2;
    Ressource ressource3;
    Ressource ressource4;
    ArrayList<UniteDeCombat> yourArmy = new ArrayList();
    ArrayList<UniteDeCombat> yourRecruts = new ArrayList();
    Ville ville = new Ville(this);
    ContourZone contour = new ContourZone((this));
    Color[] playerColor = {Color.blue, Color.yellow, Color.black, Color.orange};
    Batiment[] tabBatiment = {batiment1, batiment2, batiment3, batiment4};
    Ressource[] tabRessource = {ressource1, ressource2, ressource3, ressource4};
    ImageIcon img=new ImageIcon("imagespi\\recAtomiqueIc.png");
int quantitéDeTour=2;
 ArrayList<Renfort> listeDeRenfort = new ArrayList();
 
 
    //Image img = img = Toolkit.getDefaultToolkit().createImage("imagespi/terrainVide.png");

    public Territoire(boolean occupied, int nbPlayer) {
        this.numberOfPlayer = nbPlayer;
    int quantitéDeTour = 2;
    ArrayList<Renfort> listeDeRenfort = new ArrayList();
        id++;
        this.isOccupied = occupied;
        if (occupied) {
            createTerritory();
        } else {
            Random rnd = new Random();
            int x = rnd.nextInt(20);
            if (x < 6) {
                isTerrainDifficile = true;
            }
            add(contour);
        }

        addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                isClicked = true;
            }
        });
    }

    @Override
    public Batiment[] getBatiment() {


        return tabBatiment;
    }

    @Override
    public int getDepenseBatiment(int i) {
        for (int x = 0; x < tabBatiment.length; x++) {
            if (tabBatiment[x].getType() == i) {
                return tabBatiment[x].getDepense();
            }
        }
        return -1;
    }

    public void setTaxPercent(Double d, Faction f) {
        for (int x = 0; x < taxe.length; x++) {
            if (d == taxe[x]) {
                taxeLocation = x;
            }
        }
        setHapiness(f);

    }

    public int getID() {
        return id;
    }

    public int getSoldatNb() {
        if(living){
        return yourArmy.size();}
        return 0;
    }
public int batimentBonus(){
    int bonus=0;
    for(Batiment b:tabBatiment){
       if(b!=null){bonus=bonus+b.getProducedHapiness();}
    }
    return bonus;
}
public int rechercheBonus(Faction f){
    int bonus=0;
    f.getRecherche().getProducedHapiness();
    
    return bonus;
}
    public void setHapiness(Faction f) {
        hapiness = (int) ((int) 120 - (taxe[taxeLocation] * 2)-(basePopulation/5000)+batimentBonus()+rechercheBonus(f)+((int)getSoldatNb()/500));
        if(isCapital){
            hapiness=hapiness+20;
        }
    }

    public void addTroops(int x, int y, int z) {
        boolean eternity = true;
        while (eternity) {
            if (x != 0) {
                yourRecruts.add(new UniteTerrestreLegere(1));
                x--;
            }
            if (y != 0) {
                yourRecruts.add(new UniteTerrestreLourde(1, 5));
                y--;
            }
            if (z != 0) {
                yourRecruts.add(new UniteAerienne(1));
                z--;
            }
            if (x == 0 && y == 0 && z == 0) {
                eternity = false;
            }
        }
    }

    public int getRessourceToInt(int i) {
        int x = 0;
        try {
            x = tabRessource[i].getTypeInt();
        } catch (Exception e) {
        }

        return x;
    }

    private void createTerritory() {
        Random rnd = new Random();
        basePopulation = rnd.nextInt(100000) + 50000;
        logoVille = new LogoVille();
        route = new Route();
        barSoldat = new BarreSoldat();
        //Tout les territoires débutent avec 600 hommes- c'est la «milice», les hommes qui vont toujours rester pour protéger le territoire
        for (int x = 0; x < 600; x++) {
            yourArmy.add(new UniteTerrestreLegere(1));
        }
        for (int x = 0; x < tabRessource.length; x++) {
            tabRessource[x] = create(x + 1);
        }
        for (int x = 0; x < tabBatiment.length; x++) {
            tabBatiment[x] = new Batiment(Batiment.TypeBatiment.VIDE, Batiment.NiveauBatiment.NIV_0, x + 1, numberOfPlayer);
            add(tabBatiment[x]);
        }

        add(logoVille);
        add(barSoldat);
        add(route);
        add(contour);
        add(ville);
        for (Ressource r : tabRessource) {
            add(r);
        }


    }

    public int percentageOf(Faction f) {
        try {
            int level = f.getRecherche().getLevelOf(Recherche.TypeRecherche.AGRICULTURE, true);
            int percent = 0;
            if (level != 0) {
                percent = ((int) basePopulation * (level / 1000));
                System.out.println(percent);
                return percent;
            }
        } catch (Exception e) {
        }
        return (int) (basePopulation * 0.005);


    }
    public boolean isLiving(){
        return living;
    }
    public void actualizePopulation(Faction f,boolean b){
        if(basePopulation==0){
         logoVille.setName("Ville fantôme");
         living=false;
        }
        else if(b){
        int factor=percentageOf(f);
        basePopulation=basePopulation+factor;}
    }
    public int getDepenseRessource(int position) {
        return tabRessource[position].getCout(true);
    }

    public void upgradeRessource(int i) {

        tabRessource[i].activateConstruction();

    }
    

    public Ressource[] getRessources() {
        return tabRessource;
    }
    ///J'ai mis ca en int pcq ça sera plus court de même

    public void setPlayer(int i) {
        possessorPlayer = i;
    }

    public int getPlayer() {
        return possessorPlayer;
    }

    public void setOccupied() {
        if (!isOccupied) {
            isOccupied = true;
            isPossessed = true;
            isClicked = true;
            createTerritory();
            zoom(getWidth());
        }
    }

    @Override
    public boolean isOccupied() {
        return isOccupied;
    }

    @Override
    public boolean isClicked() {
        return isClicked;
    }

    @Override
    public void setClicked(boolean b) {
        isClicked = b;
    }

    @Override
    public int getState(int player) {
        int i = -1;
        if (isCapital && isPossessed && possessorPlayer == player) {
            i = 0;
        } else if (!isCapital && isPossessed && possessorPlayer == player) {
            i = 1;
        } else if ((!isPossessed && isOccupied) || (isPossessed && possessorPlayer != player)) {
            i = 2;
        } else if (!isOccupied && isTerrainDifficile) {
            i = 5;
        } else if (!isOccupied) {
            i = 4;
        }
        return i;
    }

    public int getPopulation() {
        return basePopulation;
    }

    public int getHapiness(Faction f) {
        setHapiness(f);
        if (hapiness < 0) {
            return 0;
        }
        
        else if (hapiness > 100) {
            return 100;
        }
        return hapiness;
    }

    public int getTaxePosition() {
        return taxeLocation;
    }
    public void civilianCrisis(){
        Random rnd=new Random();
        int losses=0;
        if(nbUniteTerrestreLegere()>800){
            losses=(rnd.nextInt(150)+50);
            newUniteTerrestreLegereList(nbUniteTerrestreLegere()-losses);
        }
        else if(nbUniteTerrestreLegere()<700&&nbUniteTerrestreLegere()>600){
            losses=700-nbUniteTerrestreLegere();
             newUniteTerrestreLegereList(600);
            
        }
        int lossesPop=losses*3;
        basePopulation=basePopulation-lossesPop;
        JOptionPane.showMessageDialog(null, "Les citoyens sont en révolte dans: "+getName()+".\nVous avez perdu "+losses+" soldats et "+lossesPop+" citoyens.");
        
    }
    public void  newUniteTerrestreLegereList(int removalNumber){
        yourArmy.removeAll(yourArmy);
        for(int i=0;i<removalNumber;i++){
            yourArmy.add(new UniteTerrestreLegere(1));
            
        }
    }
      public int getRevenuTerritoire(Faction f){
         //les territoires ont un revenu en taxes(qui dépend de la quantité de population et de la quantité de taxation
          int revenu=(int) ((int)basePopulation*(taxe[taxeLocation]*((0.0005*f.getRecherche().getLevelOf(Recherche.TypeRecherche.ECONOMIE, true))+0.001)));
          if(living){
              for(Batiment b:tabBatiment){
              revenu=revenu+b.getProfit();
          }
          for(Ressource r:tabRessource){
              revenu=revenu+r.getCout(false);
          }
         
         }
         else{revenu=0;}
          return revenu;
         
      }
        public int getDepenses(){
            int depense=0;
         if(living) {for(Batiment b:tabBatiment){
              depense=depense+b.getMaintenance();
          }}
          return depense;

    }

    public Batiment atLeastOneSpot() {

        for (Batiment b : tabBatiment) {
            if (!b.isUsed) {
                return b;
            }
        }
        return null;


    }

    public void detruire(int i) {
        getBatiment()[i].detruire();
    }

    public void privatiser(int i) {
    }

    public void nationaliser(int i) {
    }

    @Override
    public void construire(int i) {
        if (noSuchBuilding(i)) {
            Batiment x = atLeastOneSpot();
            x.setType(i);
            x.activateConstruction();
        }
    }

    public boolean noSuchBuilding(int i) {
        if (i != -1) {
            for (Batiment b : tabBatiment) {
                if (b.getType() == i) {

                    b.activateConstruction();
                    b.levelUp();
                    return false;
                }
            }
        }

        return true;
    }

    private Ressource create(int position) {
        Random rnd = new Random();
        int x = rnd.nextInt(100);
        if (x < 28) {
            return new ExploitationBois(position);
        } else if (x < 58) {
            return new MineDargent(position);
        } else if (x < 63) {
            return new MineDiamant(position);
        } else if (x < 71) {
            return new MineDor(position);
        } else {
            return new Minerai(position);
        }

    }

    public void zoom(int size) {
        super.zoom(size);
        if (isOccupied) {
            route.zoom(size);
            barSoldat.zoom(size);
            logoVille.zoom(size);
            ville.zoom(size);

            for (Batiment b : tabBatiment) {
                b.zoom(size);
            }

            for (Ressource r : tabRessource) {

                r.zoom(size);
                r.setPosition();
            }
            contour.zoom(size);
        } else {
            contour.zoom(size);
        }
    }

    public boolean isZoneInfranchissable() {
        return false;
    }

    public void setPossessed(boolean isPossessed) {
        this.isPossessed = isPossessed;
    }

    public void setCapital(boolean isCapital) {
        this.isCapital = isCapital;
    }

    @Override
    public boolean getCapital() {
        return isCapital;
    }

    @Override
    public void paintComponent(Graphics g) {
if(living){
        int i = getState(-1);
        if (isOccupied) {
            g.setColor(Color.red);
            g.fillRect(0, 0, getWidth() - 1, getHeight() - 1);
            if (isPossessed) {
                g.setColor(getPlayerColor());
                if (isClicked) {
                    g.setColor(new Color(20, 20, 20));
                }

            } else {
                g.setColor(Color.yellow);
            }
            g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
        } else {
            if (!isClicked) {
                if (i == 4) {
                    //g.drawImage(img, 0, 0, null);
                    g.setColor(new Color(0, 170, 0));
                } else {
                    g.setColor(Color.PINK);

                }
            } else {
                if (i == 4) {
                    //g.drawImage(img, 0, 0, null);
                    g.setColor(Color.green);
                } else {
                    g.setColor(new Color(0, 0, 70));

                }
            }
            g.fillRect(0, 0, getWidth() - 1, getHeight() - 1);
            g.setColor(Color.black);
            g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);

        }
}
else{removeAll();
g.setColor(Color.black);
            g.drawRect(0, 0, getWidth()-1, getHeight()-1);
g.drawImage(img.getImage(),(getWidth()/2)-(img.getImage().getWidth(null)/2), (getHeight()/2)-(img.getImage().getHeight(null)/2),null);


}

    }

    public Color getPlayerColor() {
        return playerColor[possessorPlayer];
    }

    @Override
    public boolean isZoneLibre() {
        return false;
    }

    public void timeUpgrade() {

        for (UniteDeCombat u : yourRecruts) {
            yourArmy.add(u);
        }
        yourRecruts.clear();
        barSoldat.setSoldiersNbr(yourArmy.size());
        for (Batiment b : tabBatiment) {
            if (b.isUsed()) {
                b.levelUp();
                b.getPercentageOfCompletion();
            }
        }
        for (Ressource r : tabRessource) {
            r.levelUp();
        }
    }

    @Override
    public String getName() {
        String s = " ";
        int i = getState(-1);
        if (i == 0 || i == 1 || i == 2) {
            s = logoVille.getName();
        } else if (i == 4) {
            s = "Zone libre";
        } else if (i == 5) {
            s = "Terrain difficile";
        }
        return s;
    }

    public int nbUniteTerrestreLegere() {
        int i = 0;
        for (UniteDeCombat unite : yourArmy) {
            if (unite instanceof UniteTerrestreLegere) {
                i = i + 1;
            }

        }
        return i;
    }

    public int nbUniteTerrestreLourde() {
        int i = 0;
        for (UniteDeCombat unite : yourArmy) {
            if (unite instanceof UniteTerrestreLourde) {
                i = i + 1;
            }

        }
        return i;
    }

    public int nbUniteAerienne() {
        int i = 0;
        for (UniteDeCombat unite : yourArmy) {
            if (unite instanceof UniteAerienne) {
                i = i + 1;
            }

        }
        return i;

    }
    //Dans cette méthode si genrUnite=0,on enleve des terrestre legeres si 1 terrestre lourde si 2 aerienne 

    public void perteDunite(int nbrUnite, int genreUnite, int quantiteTour, Territoire territoire) {
        boolean temp = true;
        ArrayList<UniteDeCombat> uniteEnleve = new ArrayList();
        int incrementateur = 0;
        while (incrementateur < this.yourArmy.size() && nbrUnite > uniteEnleve.size()) {
            switch (genreUnite) {
                case 0:
                    if (yourArmy.get(incrementateur) instanceof UniteTerrestreLegere) {
                        uniteEnleve.add(yourArmy.get(incrementateur));
                        incrementateur = incrementateur + 1;
                    }
                    break;
                case 1:
                    if (yourArmy.get(incrementateur) instanceof UniteTerrestreLourde) {
                        uniteEnleve.add(yourArmy.get(incrementateur));
                        incrementateur = incrementateur + 1;
                    }
                    break;
                case 2:
                    if (yourArmy.get(incrementateur) instanceof UniteAerienne) {
                        uniteEnleve.add(yourArmy.get(incrementateur));
                        incrementateur = incrementateur + 1;
                    }
                    break;



            }

        }
        this.createRenfort(uniteEnleve, quantiteTour, territoire);
        System.out.println("voici la size ke tu vx" + this.listeDeRenfort.size());
        yourArmy.removeAll(uniteEnleve);
        System.out.println("reusiiiiiiiiiiiiiiiiiiiiiiie");

    }

    public void addUnite(UniteDeCombat unite) {
        yourArmy.add(unite);

    }

    @Override
    public int getquantiteDeTour() {
        return quantitéDeTour;
    }

    public void setQuantiteTour() {
        if (this.route.getLevel() == 1) {
            this.quantitéDeTour = 1;
        } else if (this.route.getLevel() == 2) {
            this.quantitéDeTour = 0;
        }


    }

    public void createRenfort(ArrayList<UniteDeCombat> renfort, int tour, Territoire destination) {
        this.listeDeRenfort.add(new Renfort(renfort, tour, destination));
    }
    @Override
    public void removePopulation(int choice) {
        Random rnd = new Random();
        if(choice==0){
            if(basePopulation>15000){
                basePopulation=basePopulation-(rnd.nextInt(1000)+4000);
            }
            else if(basePopulation<=15000&&basePopulation>=10000){
            basePopulation=10000;
        }
        }
        else if(choice==1){
            if(basePopulation>25000){
                basePopulation=basePopulation-(rnd.nextInt(2000)+15500);
            } 
            else if(basePopulation<=25000&&basePopulation>=7500){
            basePopulation=10000;
        }
        }
        else if(choice==2){
                basePopulation=0;
            
        }
    }

    public void updateTourRenfort() {
        ArrayList<Renfort> renfortEnleve = new ArrayList();
        for (Renfort temp : this.listeDeRenfort) {
            temp.setNbTourRestant();
            temp.uniteArrived();
            if (temp.getNbTourRestant() == 0) {
                renfortEnleve.add(temp);
            }
        }
        this.listeDeRenfort.removeAll(renfortEnleve);
    }

    /*@Override
    public Image getImage() {
        return img;
    }

    @Override
    public void setImage(Image img) {
        this.img = img;
    }*/
}
